﻿using System;
using System.Collections.Generic;
using System.IO;

namespace LoLReplayHeader
{
    public class ReplayHeader
    {
        public List<Player> PlayersTeam1 = new List<Player>();
        public List<Player> PlayersTeam2 = new List<Player>();
        public ReplayFileInfo FileInfo;
        public string MapName = "";
        public TimeSpan TotalTimeSpan;

        /// <summary>
        /// Reads the header information of a League of Legends replay
        /// </summary>
        /// <param name="replayPath">Path to the replay</param>
        /// <returns>Header information of the League of Legends replay</returns>
        public static ReplayHeader ReadReplayHeader(string replayPath)
        {
            ReplayHeader replayHeader = new ReplayHeader();

            replayHeader.FileInfo = new ReplayFileInfo(new FileInfo(replayPath));

            using (FileStream stream = File.OpenRead(replayPath))
            {
                using (BinaryReader binaryReader = new BinaryReader(stream))
                {
                    int version = binaryReader.ReadInt32();
                    if (version > 100)
                    {
                        version -= 100;
                    }

                    if ((version == 3) || (version == 4))
                    {
                        replayHeader.TotalTimeSpan = TimeSpan.FromMilliseconds((double)binaryReader.ReadSingle());
                        if (version == 4)
                        {
                            replayHeader.MapName = binaryReader.ReadString();
                        }
                        int playersCount = binaryReader.ReadInt32();
                        for (int i = 0; i < playersCount; i++)
                        {
                            string summonerName = binaryReader.ReadString();
                            string ChampionWorkingName = binaryReader.ReadString();

                            if (i < playersCount / 2)
                                replayHeader.PlayersTeam1.Add(new Player(summonerName, ChampionWorkingName, GetChampionNameByWorkingName(ChampionWorkingName)));
                            else
                                replayHeader.PlayersTeam2.Add(new Player(summonerName, ChampionWorkingName, GetChampionNameByWorkingName(ChampionWorkingName)));
                        }
                        if (version != 3)
                        {
                            return replayHeader;
                        }
                        if (playersCount == 10)
                        {
                            replayHeader.MapName = "Map1";
                            return replayHeader;
                        }
                        replayHeader.MapName = "Map4";
                    }
                    return replayHeader;
                }
            }
        }

        /// <summary>
        /// Gets the champion name
        /// </summary>
        /// <param name="championWorkingName">Champion working name</param>
        /// <returns>Champion name</returns>
        public static string GetChampionNameByWorkingName(string championWorkingName)
        {
            Dictionary<string, string> ChampionNamesDictionary = new Dictionary<string, string>();

            ChampionNamesDictionary.Add("Armordillo", "Rammus");
            ChampionNamesDictionary.Add("Armsmaster", "Jax");
            ChampionNamesDictionary.Add("Bowmaster", "Ashe");
            ChampionNamesDictionary.Add("CardMaster", "Twisted Fate");
            ChampionNamesDictionary.Add("ChemicalMan", "Singed");
            ChampionNamesDictionary.Add("Chronokeeper", "Zilean");
            ChampionNamesDictionary.Add("Cryophoenix", "Anivia");
            ChampionNamesDictionary.Add("DarkChampion", "Tryndamere");
            ChampionNamesDictionary.Add("FallenAngel", "Morgana");
            ChampionNamesDictionary.Add("GemKnight", "Taric");
            ChampionNamesDictionary.Add("GreenTerror", "Cho'gath");
            ChampionNamesDictionary.Add("Jester", "Shaco");
            ChampionNamesDictionary.Add("Judicator", "Kayle");
            ChampionNamesDictionary.Add("Lich", "Karthus");
            ChampionNamesDictionary.Add("Minotaur", "Alistar");
            ChampionNamesDictionary.Add("Pirate", "Gangplank");
            ChampionNamesDictionary.Add("SteamGolem", "Blitzcrank");
            ChampionNamesDictionary.Add("Voidwalker", "Kassassadin");
            ChampionNamesDictionary.Add("Wolfman", "Warwick");
            ChampionNamesDictionary.Add("XenZhao", "Xin Zhao");
            ChampionNamesDictionary.Add("Yeti", "Nunu");

            if (ChampionNamesDictionary.ContainsKey(championWorkingName))
            {
                return ChampionNamesDictionary[championWorkingName];
            }

            return championWorkingName;
        }
    }

    /// <summary>
    /// Class with player structure
    /// </summary>
    public class Player
    {
        public string SummonerName;
        public string ChampionName;
        public string ChampionWorkingName;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="summonerName">Summoner name</param>
        /// <param name="championWorkingName">Champion working name</param>
        /// <param name="championName">Champion name</param>
        public Player(string summonerName, string championWorkingName, string championName)
        {
            this.SummonerName = summonerName;
            this.ChampionName = championName;
            this.ChampionWorkingName = championWorkingName;
        }

    }

    /// <summary>
    /// Class with replay file infos
    /// </summary>
    public class ReplayFileInfo
    {
        public string FileName;
        public string Directory;
        public string FullPath;
        public double FileSizeInMb;
        public long FileSizeInByte;
        public DateTime Created;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="fileInfo">FileInfo object</param>
        public ReplayFileInfo(FileInfo fileInfo)
        {
            Created = fileInfo.CreationTime;
            Directory = fileInfo.DirectoryName;
            FileName = fileInfo.Name;
            FileSizeInByte = fileInfo.Length;
            FileSizeInMb = (double)fileInfo.Length / 1024 / 1024;
            FullPath = fileInfo.FullName;
        }
    }
}
